//////////////////////////////////////////////////////////////////////////
//
// This file is a part of APNS provider project.
// Copyright (c) Vladimir Gumenuk, 2013-2014.
//
// PROJECT:         APNS provider
// FILE:            APNSClient.h
// AUTHOR:          Vladimir Gumenuk
// DATE:            22-Dec-2013
// MODIFICATIONS:
//
//////////////////////////////////////////////////////////////////////////

#pragma once

class ATL_NO_VTABLE CAPNSClient :
    public CComObjectRootEx<CComMultiThreadModel>,
    public IAPNSClient
{
public:
    CAPNSClient();
    virtual ~CAPNSClient();

BEGIN_COM_MAP(CAPNSClient)
    COM_INTERFACE_ENTRY_IID(IID_IAPNSClient,IAPNSClient)
END_COM_MAP()

static HRESULT Create( IAPNSClient **ppOut );

STDMETHOD(Connect)( IGMSNetwork *pNet, LPCTSTR lpszCertSubject, LPCTSTR lpszServerName, DWORD dwPortNumber );
STDMETHOD(Disconnect)();
STDMETHOD(SendNotification)( IPushNotification *pNtfs );

private:
    BOOL LoadSecurityLibrary();
    void UnloadSecurityLibrary();
    
    HRESULT CreateCredentials( LPCTSTR pszUser, PCredHandle phCreds );
    void GetNewClientCredentials( CredHandle *phCreds, CtxtHandle *phContext );
    void DisplayConnectionInfo( CtxtHandle *phContext );
    
    HRESULT ClientHandshakeLoop( PCredHandle phCreds, CtxtHandle *phContext, BOOL bDoInitialRead, SecBuffer *pExtraData );
    HRESULT PerformClientHandshake( PCredHandle phCreds, LPCTSTR pszServerName, CtxtHandle *phContext, SecBuffer *pExtraData );

    HRESULT EncryptSend( LPBYTE pBuffer, DWORD dwMsgLen );
    HRESULT ReadDecrypt( LPBYTE pBuffer, DWORD dwBufLen );

    HRESULT SendNotificationsRaw( IGMSBuffer *pBuf );

    CredHandle                  m_hClientCreds;
    CtxtHandle                  m_hContext;
    BOOL                        m_bCredsInitialized;
    BOOL                        m_bContextInitialized;
    
    DWORD                       m_dwProtocol;       // security protocol code
    ALG_ID                      m_aiKeyExch;        // key exchange algorithm used

    HCERTSTORE                  m_hCertStore;       // certificate storage
    HMODULE                     m_hSecurity;

    SCHANNEL_CRED               m_SchannelCred;
    PSecurityFunctionTable      m_pSSPI;
    SecPkgContext_StreamSizes   m_StreamSizes;      // secure channel io buffer sizes
    LPBYTE                      m_pIoBuffer;        // input/output buffer
    DWORD                       m_dwIoBufLen;       // buffer length

    CComPtr<IGMSNetwork>        m_spNetwork;
    CComPtr<IGMSNetClient>      m_spNetClient;
};

